package com.hts.redis.redisson;

import cn.hutool.core.util.IdUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @author 洪松
 */
@Slf4j
public class RedissonTemplate {
    private final RedissonClient redissonClient;

    public RedissonTemplate(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @SneakyThrows
    public <T> Optional<T> autoLock(String key, Long second, Supplier<T> supplier) {
        RLock lock = redissonClient.getLock(key);
        Boolean lockResult = lock.tryLock(second, TimeUnit.SECONDS);
        //加锁失败
        if (Boolean.FALSE.equals(lockResult)) {
            return Optional.empty();
        }
        //用于校验是否锁的追踪
        Long lockId = IdUtil.getSnowflakeNextId();
        try {
            log.info("加锁成功：锁的号:{}",lockId);
            return Optional.ofNullable(supplier.get());
        } finally {
            log.info("释放锁：锁的号:{}",lockId);
            lock.unlock();
        }
    }


    public <T> Optional<T> autoLock(String key, Supplier<T> supplier) {
        return autoLock(key, -1L, supplier);
    }


    @SneakyThrows
    public void autoLock(String key, Runnable runnable) {
        RLock lock = redissonClient.getLock(key);
        Boolean lockResult = lock.tryLock(-1, TimeUnit.SECONDS);
        //加锁失败
        if (Boolean.FALSE.equals(lockResult)) {
            return;
        }
        Long lockId = IdUtil.getSnowflakeNextId();
        try {
            //用于校验是否锁的追踪
            log.info("加锁成功：锁的号:{}",lockId);
            runnable.run();
        } finally {
            log.info("释放锁：锁的号:{}",lockId);
            lock.unlock();
        }
    }

}
